package com.citycloud.ccuap.tc.admin.project;

import com.citycloud.ccuap.commons.constants.GlobalOperateType;
import com.citycloud.ccuap.commons.json.JSONData;
import com.citycloud.ccuap.commons.openapi.controller.base.BaseController;
import com.citycloud.ccuap.commons.sys.entity.SysProject;
import com.citycloud.ccuap.commons.sys.entity.SysProjectCategory;
import com.citycloud.ccuap.commons.sys.entity.SysRole;
import com.citycloud.ccuap.commons.sys.projectcategory.IProjectCategoryService;
import com.citycloud.ccuap.commons.sys.repository.SysRoleRepository;
import com.citycloud.ccuap.commons.web.session.CurrentUser;
import com.citycloud.ccuap.commons.web.util.ResolveRequest;
import com.citycloud.ccuap.framework.exception.AppAssert;
import com.citycloud.ccuap.framework.exception.ApplicationException;
import com.citycloud.ccuap.framework.mybatis.pagination.PageQuery;
import com.citycloud.ccuap.framework.util.ClassUtil;
import com.citycloud.ccuap.framework.util.DateUtil;
import com.citycloud.ccuap.framework.util.StringUtil;
import com.citycloud.ccuap.tc.admin.defaultrole.DefaultRole;
import com.citycloud.ccuap.tc.admin.defaultrole.IDefaultRoleService;
import com.citycloud.ccuap.tc.admin.entity.*;
import com.citycloud.ccuap.tc.admin.enums.DefaultSiteTypeCode;
import com.citycloud.ccuap.tc.admin.projectdefaultfunction.IProjectDefaultFunctionService;
import com.citycloud.ccuap.tc.admin.projectdgrel.IProjectDgRelService;
import com.citycloud.ccuap.tc.admin.projectfunction.IProjectFunctionService;
import com.citycloud.ccuap.tc.admin.projectrelapp.SysProjectRelAppService;
import com.citycloud.ccuap.tc.admin.projecttype.IProjectTypeService;
import com.citycloud.ccuap.tc.admin.repository.*;
import com.citycloud.ccuap.tc.admin.sec.secuser.ISecUserCacheService;
import com.citycloud.ccuap.tc.admin.sec.secuser.SecUserMapper;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "项目（站点）信息")
@RestController("yqProjectController")
@RequestMapping("/v1/yq/project")
public class ProjectController extends BaseController {

	@Autowired
	ISecUserCacheService secUserCacheService;

	@Autowired
	@Lazy
	SecUserMapper secUserMapper;

	@Autowired
	private IProjectService projectService;

	@Autowired
	@Qualifier("sysYqProjectRepository")
	private SysYqProjectRepository sysProjectRepository;
	
	@Autowired
	private IProjectCategoryService projectCategoryService;
	@Autowired
	private IProjectDefaultFunctionService prjectDefaultFunctionService;

	@Autowired
	private IProjectFunctionService projectFunctionService;

	@Autowired
	private IProjectDgRelService projectDgRelService;

	@Autowired
	private SysRoleRepository sysRoleRepository;
	@Autowired
	private SysProjectRelAppService sysProjectRelAppService;
	@Autowired
	private SysAppRepository sysAppRepository;
	@Autowired
	private OauthClientDetailsRepository oauthClientDetailsRepository;
	@Autowired
	private IProjectTypeService projectTypeService;
	@Autowired
	private SysProjectRelAppRepository sysProjectRelAppRepository;
	@Autowired
	private IDefaultRoleService iDefaultRoleService;

	@Autowired
	private SysProjectDefaultFunctionRepository sysProjectDefaultFunctionRepository;

	private static final String PROJECT_CODE_PREFIX="project_";

	/**
	 * 默认构造函数
	 */
	public ProjectController() {
	}
	
	
	/**
	 * 获取站点下拉列表
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/getProjectTextId", method = { RequestMethod.GET, RequestMethod.POST })
	@ApiOperation( value = "获取站点下拉列表",notes = "getProjectTextId")
	public JSONData getProjectTextId() throws Exception {
		//TODO 缺少模糊查询
		List<Map<String,Object>> list = projectService.getProjectTextId();
		return new JSONData(list);
	}
	
	
	@ApiOperation("根据主键获取对象")
	@RequestMapping(value = "/findById", method = { RequestMethod.GET, RequestMethod.POST })
	public JSONData findById() throws Exception {
		Long projectId = getLongParameter("projectId");
		SysProject sysProject = projectService.findById(projectId);
//		SysProjectRelApp sysProjectRelApp = sysProjectRelAppService.getSysProjectRelAppByProjectId(sysProject.getProjectId());
		SysApp sysApp = sysAppRepository.findByClientIdOrderByAppIdDesc(sysProject.getClientId());
		SysProjectDto dto = new SysProjectDto();
		BeanUtils.copyProperties(sysProject, dto);
		if (sysApp != null) {
			dto.setAppType(sysApp.getAppType());
//			dto.setAppType(sysProjectRelApp.getAppType());
//			dto.setClientId(sysProjectRelApp.getClientId());
//			dto.setObjId(sysProjectRelApp.getObjId());
//			dto.setProjectId(sysProjectRelApp.getProjectId());
//			//返回项目类型
//			dto.setProjectTypeId(sysProjectRelApp.getProjectTypeId());
		}
		JSONData jsonData = new JSONData(dto);
		return jsonData;
	}
	
	/**
	 * 获取页面提交的对象
	 *
	 * @return struts result
	 * @throws Exception
	 */
	private SysProject getRequestDataObject(short operateType) throws Exception {
		SysProject sysProject = new SysProject();
		ResolveRequest.fillData(request, sysProject);
		
		CurrentUser user = super.getCurrentUser();
		if (GlobalOperateType.ADD == operateType) {
			sysProject.setCreator(user.getUser().getUserNo());
			sysProject.setCreatedTime(DateUtil.getCurrentDateTime());
			sysProject.setDataStatus((short) 0);
//			sysProject.setDeleted(false);
			if(StringUtils.isBlank(sysProject.getProjectNo())){
				String code = UUID.randomUUID().toString().replace("-", "");
				// 编码 数据库长度限制32 需要修改长度
				sysProject.setProjectNo( PROJECT_CODE_PREFIX + code);
			}
			if(sysProject.getMqOff() == null){
				sysProject.setMqOff(false);
			}
//			if(sysProject.getEnvironmentFlag() == null){
//				sysProject.setEnvironmentFlag("0");
//			}
		} else if (GlobalOperateType.EDIT == operateType) {
			sysProject.setUpdator(user.getUser().getUserNo());
			sysProject.setUpdatedTime(DateUtil.getCurrentDateTime());
//			sysProject.setUrl(new StringBuilder(YunQingConfigurer.yunQingAppUrl).append("/app/index.html?id=")
//									  .append(sysProject.getProjectId()).toString());
		}
		
		return sysProject;
	}
	
	@ApiOperation("新增对象")
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public JSONData add() throws Exception {
		SysProject sysProject = getRequestDataObject(GlobalOperateType.ADD);
		sysProject.setDataStatus(Short.valueOf("1"));
		List<SysProject> projectNoList = sysProjectRepository.findByProjectNo(sysProject.getProjectNo());
		if (projectNoList != null && projectNoList.size() > 0) {
			throw new ApplicationException(500,"编码不能重复！");
		}

		List<SysProject> nameList = sysProjectRepository.findByProjectNameAndDataStatusIs(sysProject.getProjectName(),true);
		if (nameList != null && nameList.size() > 0) {
			throw new ApplicationException(500,"名称不能重复！");
		}
		projectService.insert(sysProject);
//		if(StringUtils.isEmpty(sysProject.getUrl())){
//			sysProject.setUrl(new StringBuilder(YunQingConfigurer.yunQingAppUrl).append("/app/index.html?id=")
//					.append(sysProject.getProjectId()).toString());
//			projectService.save(sysProject);
//		}
		//新增时，站点菜单默认从“站点默认菜单”拷贝

		String projectTypeId = request.getParameter("projectTypeId");
		AppAssert.hasText(projectTypeId,"站点类型不能为空！");
		if(StringUtils.isNotBlank(projectTypeId)){
			// 当站点所属数据中台时，才所属默认菜单
			saveProjectFunction(sysProject, projectTypeId);
		}
		// 添加到站点应用关联表
		String appType = request.getParameter("appType");
		AppAssert.hasText(appType, 500,"应用类型不能为空！");

		String appId = request.getParameter("clientId");
		AppAssert.hasText(appId,500,"应用不能为空！");

		// 修改站点列表为scope里面元素
		OauthClientDetails oauthClientDetails=oauthClientDetailsRepository.findByClientId(appId);
        if (oauthClientDetails != null) {
			List<String> list = new ArrayList<>();
        	if(StringUtils.isNotEmpty(oauthClientDetails.getScope())){
				list = Arrays.stream(oauthClientDetails.getScope().split(",")).
						filter(s -> !s.equals(sysProject.getProjectId().toString())).collect(Collectors.toList());
			}
            list.add(sysProject.getProjectId().toString());
            oauthClientDetails.setScope(String.join(",",list));
			logger.info("oauthClientDetails.getScope:{"+oauthClientDetails.getScope()+"}");
            oauthClientDetailsRepository.updateIgnoreNull(oauthClientDetails);
        }
		JSONData jsonData= changeStatus(sysProject.getProjectId(),sysProject.getDataStatus());
		//sys_project_default_role 所有角色复制到sys_role 表
//		CopyRole(sysProject.getProjectId());
		if(jsonData.getSuccess()) {
			return new JSONData("添加站点信息成功！");
		}else {
			return jsonData;
		}
	}

	private void saveProjectFunction(SysProject sysProject, String projectTypeId) {
		SysProjectType projectType = projectTypeService.findById(projectTypeId);
		if(projectType != null && DefaultSiteTypeCode.DATAC.getValue().equals(projectType.getCode())){
            List<SysProjectDefaultFunction> defaultFunctionList = prjectDefaultFunctionService.selectList();
            List<SysProjectFunction> functionList = new ArrayList<>();
            for(SysProjectDefaultFunction defaultFunction:defaultFunctionList){
                SysProjectFunction sysProjectFunction = new SysProjectFunction();
                ClassUtil.copyProperties(defaultFunction, sysProjectFunction);
                sysProjectFunction.setProjectId(sysProject.getProjectId());
                sysProjectFunction.setFunId(defaultFunction.getFunId()+"_"+sysProject.getProjectId());
                if(StringUtils.isNotEmpty(defaultFunction.getPid())) {
                    sysProjectFunction.setPid(defaultFunction.getPid()+"_"+sysProject.getProjectId());
                }
                functionList.add(sysProjectFunction);
            }
            projectFunctionService.insert(functionList);
        }
	}

	@ApiOperation("更新对象")
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	public JSONData update() throws Exception {
		String appType = request.getParameter("appType");
		String projectTypeId= request.getParameter("projectTypeId");
		String appId = request.getParameter("clientId");
		AppAssert.hasText(appType, 500,"应用类型不能为空！");
		AppAssert.hasText(projectTypeId, 500, "站点类型不能为空！");
		AppAssert.hasText(appId, 500,"关联应用不能为空！");
		SysProject sysProject = getRequestDataObject(GlobalOperateType.EDIT);
		projectService.modify(sysProject);
		SysApp sysApp=sysAppRepository.findByClientIdOrderByAppIdDesc(sysProject.getClientId());
		// 更新站点应用关联表
		if (sysApp != null) {
            // 修改站点列表为scope里面元素
            OauthClientDetails oauthClientDetails=oauthClientDetailsRepository.findByClientId(appId);
            if (oauthClientDetails != null) {
				List<String> list = new ArrayList<>();
				if(StringUtils.isNotEmpty(oauthClientDetails.getScope())){
					list = Arrays.stream(oauthClientDetails.getScope().split(",")).
							filter(s -> !s.equals(sysProject.getProjectId().toString())).collect(Collectors.toList());
				}
                list.add(sysProject.getProjectId().toString());
                oauthClientDetails.setScope(String.join(",",list));
				logger.info("oauthClientDetails.getScope:{"+oauthClientDetails.getScope()+"}");
                oauthClientDetailsRepository.updateIgnoreNull(oauthClientDetails);
            }
		}
		JSONData jsonData= changeStatus(sysProject.getProjectId(),sysProject.getDataStatus());
		if(jsonData.getSuccess()) {
			return new JSONData("修改站点信息成功！");
		}else {
			return jsonData;
		}
	}


	@ApiOperation("删除对象")
	@RequestMapping(value = "/delete", method = RequestMethod.POST)
	public JSONData delete() throws Exception {
		Long projectId = getLongParameter("projectId");
		//逻辑删除
		projectService.deleteLogic(projectId);

		return new JSONData("删除站点信息成功！");
	}

	@ApiOperation("删除多个对象")
	@RequestMapping(value = "/deleteList", method = RequestMethod.POST)
	public JSONData deleteList() throws Exception {
		String projectIds = getStringParameter("projectIds");
		List<Long> projectIdList = StringUtil.strToLongList(projectIds);

		projectService.deleteIdList(projectIdList);

		JSONData jsonData = new JSONData("删除站点信息成功！");
		return jsonData;
	}
	
	@ApiOperation("根据条件查询对象")
	@RequestMapping(value = "/query", method = { RequestMethod.GET, RequestMethod.POST })
	public JSONData query() throws Exception {
		PageQuery<Map<String, Object>> pageQuery = ResolveRequest.getPageForParams(request);
		Long catId = getLongParameter("q_catId");
		List<SysProjectCategory> allChildList = projectCategoryService.getAllChildList(catId);
		if(catId!=null) {
			allChildList.add(projectCategoryService.findById(catId));
		}
		String catIdList=getCateIdStr(catId, allChildList);
		String cond = getStringParameter("q_cond");
		String fitetype = getStringParameter("q_filtertype");
		String sql = "select sp.*,type.NAME AS project_type,app.app_type,app.app_name  from sys_project sp LEFT JOIN sys_project_type type ON type.id = sp.project_type_id " +
				" LEFT JOIN sys_app app ON app.client_id = sp.client_id "+
//				"where (sp.data_status = 1) ";
				"where (1 = 1) ";
//				"where (sp.deleted = 0 or sp.deleted is null) ";
		if (StringUtils.isNotEmpty(catIdList)) {
			sql += " and cat_id in(" + catIdList+")";
		}
		if (StringUtils.isNotBlank(cond)) {
			if("1".equals(fitetype)){
				sql += " and  ( sp.project_name like '%" + cond + "%'"+")";
			}else{
				sql += " and (sp.project_no like '%" + cond + "%' or sp.project_name like '%" + cond + "%' or sp.manager_names like '%" + cond + "%')";
			}
		}
		sql += " order by sp.data_status desc,sp.created_time desc";
		PageQuery<Map<String, Object>> pageData = projectService.selectPage(pageQuery, sql, true);
		List<Map<String, Object>> records = pageData.getRecords();
		Optional.ofNullable(records).orElseGet(()->{
			return  Lists.newArrayList();
		}).stream().forEach(s -> {
			s.put("createdTime", Objects.toString(s.get("createdTime")).split("\\.")[0]);
		});
		pageData.setRecords(records);
		JSONData jsonData = new JSONData(pageData);
		return jsonData;
	}
	
	private String getCateIdStr(Long catId,List<SysProjectCategory> allChildList) {
		StringBuilder sqlFilterBuilder = new StringBuilder();
		for(int i=0; i<allChildList.size(); i++) {
			if(i==allChildList.size()-1) {
				sqlFilterBuilder.append(allChildList.get(i).getCatId()).append("");
			}else {
				sqlFilterBuilder.append(allChildList.get(i).getCatId()).append(",");
			}
			
		}
		return sqlFilterBuilder.toString();
	}
	
	@ApiOperation("管理员授权")
	@RequestMapping(value = "/updateManagerInfo", method = RequestMethod.POST)
	public JSONData updateManagerInfo(@RequestBody ProjectUserDTO projectUser) throws Exception {
		AppAssert.notNull(projectUser,"传入的参数不能为空");
		projectService.updateManagerInfo(projectUser);
		JSONData jsonData = new JSONData("站点管理员配置成功！");
		return jsonData;
	}
	
	@ApiOperation("查询站点管理员信息")
	@RequestMapping(value = "/findUsersById", method = RequestMethod.POST)
	public JSONData findUsersById() throws Exception {
		Long projectId = getLongParameter("projectId");
		List<Map<String, Object>> userList = projectService.findUsersInfoById(projectId);
		JSONData jsonData = new JSONData(userList);
		return jsonData;
	}
	
	@ApiOperation("更新数据组权限")
	@RequestMapping(value = "/updateDataGroupInfo", method = { RequestMethod.GET, RequestMethod.POST })
	public JSONData updateDataGroupInfo(){
		Long projectId = getLongParameter("projectId");
		String[] dataGroupIds = getStringParameter("dataGroupIds").split("#");
		projectDgRelService.deleteByProjectId(projectId);
		for(String id : dataGroupIds) {
			if(StringUtils.isNotBlank(id)) {
				SysProjectDgRel projectDgRel = new SysProjectDgRel();
				projectDgRel.setProjectId(projectId);
				projectDgRel.setDatagroupId(id);
				projectDgRelService.save(projectDgRel);
			}
		}
		secUserMapper.deleteUnUseredByProjectId(projectId);
		for(String id : dataGroupIds) {
			if(StringUtils.isNotBlank(id)) {
				secUserCacheService.buildRolesDataGroupCacheByDataGroupId(id);
			}
		}
		JSONData jsonData = new JSONData("站点数据组配置成功");
		return jsonData;
	}
	
	@ApiOperation("获取数据组权限")
	@RequestMapping(value = "/getDataGroupsById", method = { RequestMethod.GET, RequestMethod.POST })
	public JSONData getDataGroupsById(){
		Long projectId = getLongParameter("projectId");
		List<Map<String, Object>> result = projectService.findDataGroupInfoById(projectId);
		JSONData jsonData = new JSONData(result);
		return jsonData;
	}
	
	@ApiOperation("获取菜单节点")
	@RequestMapping(value = "/changeStatus", method = {RequestMethod.GET, RequestMethod.POST})
	public JSONData changeStatus() throws Exception {
		JSONData jsonData = changeStatus(getLongParameter("projectId"),null);
		return jsonData;
	}
	
	private JSONData changeStatus(Long projectId, Short status) throws Exception {

		SysProject project = projectService.findById(projectId);
//		JSONObject jsonParam = new JSONObject();
		if(status==null) {
			if(((short) 0) == project.getDataStatus()) {
				project.setDataStatus((short) 1);
//				jsonParam.put("deleted", true);
			} else {
				project.setDataStatus((short) 0);
//				jsonParam.put("deleted", false);
			}
		}
		else {
			project.setDataStatus(status);
//			if(status==0) {
//				jsonParam.put("deleted", false);
//			}else {
//				jsonParam.put("deleted", true);
//			}
		}


		CurrentUser user = getCurrentUser();
//		String url = YunQingConfigurer.yunQingUrl + "/ccuap/tenant/changeState";
//		jsonParam.put("tenantId", project.getProjectId());
//		jsonParam.put("userName", user.getUser().getUserName());
//		jsonParam.put("userId", user.getUser().getUserId());
//		jsonParam.put("name", project.getProjectName());
//
//		Map<String, String> headers = new HashMap<>();
//		headers.put("access_token", YunQingConfigurer.TenantAccessheader);
//		String resultJson ="";
//		try {
//			resultJson = YqUtils.httpPostWithJSON(url, jsonParam, headers);
//		}catch (Exception e){
//			resultJson="{CODE:CODE}";
//		}
//		Map<String, Object> resultMap = JSONUtil.convertJsonToMap(resultJson);
//		if (resultMap.get("CODE").equals("FAILURE")) {
//			JSONData jsonData = new JSONData(false, resultMap.get("MESSAGE").toString());
//			return jsonData;
//		} else {
			projectService.modify(project);
			JSONData jsonData = new JSONData(project);
			return jsonData;
//		}

	}

//	@ApiOperation("根据projectId获取clientId")
//	@RequestMapping(value = "/getClientIdFromProjectId", method = { RequestMethod.GET, RequestMethod.POST })
//	public JSONData getClientIdFromProjectId(){
//		Long projectId = getLongParameter("projectId");
//		String sql="select client_id clientId from sys_project_rel_app where project_id="+projectId;
//		List<Map<String, Object>> list = sysProjectRelAppService.selectList(sql);
//		String cilentId=null;
//		if(!CollectionUtils.isEmpty(list)){
//			cilentId= (String) list.get(0).get("clientId");
//		}
//		JSONData jsonData = new JSONData(cilentId);
//		return jsonData;
//	}

	public void copyRole(Long projectId){

		try {
			//sys_project_default_role 所有角色复制到sys_role 表
			List<DefaultRole> defaultRoleList=iDefaultRoleService.getAll();
			for (DefaultRole defaultRole :defaultRoleList){
				SysRole sysRole=new SysRole();
				sysRole.setProjectId(projectId);
				sysRole.setCreatedTime(new Date());
				sysRole.setDataStatus(Short.valueOf("1"));
				sysRole.setRoleCode(defaultRole.getRoleCode());
				sysRole.setRoleName(defaultRole.getRoleName());
				sysRole.setJson("{}");
				sysRole.setCreator("admin");
				sysRoleRepository.insert(sysRole);
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}
}